#include "../includes/FileApi.h"
#include <iostream>
#include <string>
#include <thread>
#include <vector>
#include <cassert>
#include <cstring>
#include <fstream>

class FileApiTest {
private:
    FileApi& file_api;

public:
    FileApiTest() : file_api(FileApi::getInstance()) {}

    // 测试单线程文件创建和写入
    void test_single_thread_write() {
        std::cout << "=== 测试单线程文件创建和写入 ===" << std::endl;
        
        const std::string test_file = "/test_single_write.txt";
        const char* test_data = "Hello, File System! This is a single thread write test.";
        size_t data_size = strlen(test_data);
        
        // 打开文件
        int fd = file_api.open(test_file);
        assert(fd != -1);
        std::cout << "文件句柄: " << fd << std::endl;
        
        // 写入数据
        int result = file_api.write(fd, (void*)test_data, data_size);
        assert(result == static_cast<int>(data_size));
        std::cout << "成功写入 " << result << " 字节数据" << std::endl;
        
        // 关闭文件
        file_api.close(fd);
        
        std::cout << "单线程写入测试通过!" << std::endl << std::endl;
    }

    // 测试单线程文件读取
    void test_single_thread_read() {
        std::cout << "=== 测试单线程文件读取 ===" << std::endl;
        
        const std::string test_file = "/test_single_write.txt";
        const char* expected_data = "Hello, File System! This is a single thread write test.";
        size_t expected_size = strlen(expected_data);
        
        // 打开文件
        int fd = file_api.open(test_file);
        assert(fd != -1);
        
        // 读取数据
        char buffer[256];
        int result = file_api.read(fd, buffer, expected_size);
        assert(result == static_cast<int>(expected_size));
        
        // 验证数据
        buffer[result] = '\0';
        assert(strcmp(buffer, expected_data) == 0);
        std::cout << "读取的数据: " << buffer << std::endl;
        
        // 关闭文件
        file_api.close(fd);
        
        std::cout << "单线程读取测试通过!" << std::endl << std::endl;
    }

    // 测试多次写入和读取
    void test_multiple_write_read() {
        std::cout << "=== 测试多次写入和读取 ===" << std::endl;
        
        const std::string test_file = "/test_multiple.txt";
        
        // 打开文件
        int fd = file_api.open(test_file);
        assert(fd != -1);
        
        // 第一次写入
        const char* data1 = "First write: ";
        const char* data2 = "Second write: Hello World!";
        const char* expected = "First write: Second write: Hello World!";
        
        int result1 = file_api.write(fd, (void*)data1, strlen(data1));
        assert(result1 == static_cast<int>(strlen(data1)));
        
        int result2 = file_api.write(fd, (void*)data2, strlen(data2));
        assert(result2 == static_cast<int>(strlen(data2)));
        
        std::cout << "写入数据1: " << data1 << " (" << result1 << " 字节)" << std::endl;
        std::cout << "写入数据2: " << data2 << " (" << result2 << " 字节)" << std::endl;
        
        // 关闭写入文件句柄
        file_api.close(fd);
        
        // 重新打开文件读取
        int read_fd = file_api.open(test_file);
        assert(read_fd != -1);
        
        char buffer[256];
        int read_result = file_api.read(read_fd, buffer, strlen(expected));
        assert(read_result == static_cast<int>(strlen(expected)));
        buffer[read_result] = '\0';
        
        assert(strcmp(buffer, expected) == 0);
        std::cout << "读取的数据: " << buffer << std::endl;
        
        // 关闭读取文件句柄
        file_api.close(read_fd);
        
        std::cout << "多次写入读取测试通过!" << std::endl << std::endl;
    }

    // 测试大文件写入（测试多块分配）
    void test_large_file_write() {
        std::cout << "=== 测试大文件写入 ===" << std::endl;
        
        const std::string test_file = "/test_large_file.txt";
        
        // 创建大文件数据（超过一个BLOCK_SIZE）
        std::string large_data;
        for(int i = 0; i < 50; i++) {
            large_data += "This is a large test data block " + std::to_string(i) + ". ";
            large_data += "abcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+ ";
        }
        
        // 打开文件
        int fd = file_api.open(test_file);
        assert(fd != -1);
        
        // 写入大文件
        int result = file_api.write(fd, (void*)large_data.c_str(), large_data.length());
        assert(result == static_cast<int>(large_data.length()));
        
        std::cout << "大文件写入 " << result << " 字节成功!" << std::endl;
        
        // 关闭写入文件句柄
        file_api.close(fd);
        
        // 验证大文件读取
        int read_fd = file_api.open(test_file);
        assert(read_fd != -1);
        
        char* read_buffer = new char[large_data.length() + 1];
        int read_result = file_api.read(read_fd, read_buffer, large_data.length());
        assert(read_result == static_cast<int>(large_data.length()));
        
        read_buffer[read_result] = '\0';
        assert(strcmp(read_buffer, large_data.c_str()) == 0);
        
        delete[] read_buffer;
        
        // 关闭读取文件句柄
        file_api.close(read_fd);
        
        std::cout << "大文件读取验证成功!" << std::endl;
        std::cout << "大文件测试通过!" << std::endl << std::endl;
    }

    // 测试并发写入
    void test_concurrent_write() {
        std::cout << "=== 测试并发写入 ===" << std::endl;
        
        const std::string test_file = "/test_concurrent.txt";
        
        // 使用lambda表达式创建多个线程写入
        int fd = file_api.open(test_file);
        auto write_thread = [&](int thread_id) {
            std::string thread_data = "Thread " + std::to_string(thread_id) + " data. ";
            if(fd != -1) {
                file_api.write(fd, (void*)thread_data.c_str(), thread_data.length());
                std::cout << "线程 " << thread_id << " 写入完成" << std::endl;
                
            }
        };
        // 关闭当前线程的文件句柄
        file_api.close(fd);
        
        std::vector<std::thread> threads;
        for(int i = 0; i < 3; i++) {
            threads.emplace_back(write_thread, i);
        }
        
        for(auto& t : threads) {
            t.join();
        }
        
        std::cout << "并发写入测试完成!" << std::endl;
        std::cout << "并发写入测试通过!" << std::endl << std::endl;
    }

    // 测试错误处理
    void test_error_handling() {
        std::cout << "=== 测试错误处理 ===" << std::endl;
        
        // 测试无效文件句柄
        char buffer[100];
        int invalid_fd = 9999; // 一个不存在的文件句柄
        int result = file_api.read(invalid_fd, buffer, sizeof(buffer));
        assert(result == -1);
        std::cout << "无效句柄读取测试通过" << std::endl;
        
        result = file_api.write(invalid_fd, buffer, sizeof(buffer));
        assert(result == -1);
        std::cout << "无效句柄写入测试通过" << std::endl;
        
        std::cout << "错误处理测试通过!" << std::endl << std::endl;
    }

    // 测试文件句柄管理
    void test_file_handle_management() {
        std::cout << "=== 测试文件句柄管理 ===" << std::endl;
        
        std::vector<int> file_handles;
        
        // 打开多个文件
        for(int i = 0; i < 10; i++) {
            std::string filename = "/test_handle_" + std::to_string(i) + ".txt";
            int fd = file_api.open(filename);
            assert(fd != -1);
            file_handles.push_back(fd);
            
            std::string data = "Data for file " + std::to_string(i);
            file_api.write(fd, (void*)data.c_str(), data.length());
            
            // 立即关闭写入句柄
            file_api.close(fd);
        }
        
        std::cout << "成功打开 " << file_handles.size() << " 个文件" << std::endl;
        
        // 验证每个文件的内容 - 需要重新打开
        for(size_t i = 0; i < file_handles.size(); i++) {
            std::string filename = "/test_handle_" + std::to_string(i) + ".txt";
            int fd = file_api.open(filename);
            assert(fd != -1);
            
            std::string expected_data = "Data for file " + std::to_string(i);
            char buffer[256];
            file_api.lseek(fd, 0, SEEK_SET); // 重置文件读写偏移量
            int result = file_api.read(fd, buffer, expected_data.length());
            assert(result == static_cast<int>(expected_data.length()));
            buffer[result] = '\0';
            assert(strcmp(buffer, expected_data.c_str()) == 0);
            
            // 关闭读取句柄
            file_api.close(fd);
        }
        
        std::cout << "文件句柄管理测试通过!" << std::endl << std::endl;
    }

    // 测试 close 功能
    void test_close_functionality() {
        std::cout << "=== 测试 close 功能 ===" << std::endl;
        
        const std::string test_file = "/test_close.txt";
        
        // 打开文件
        int fd = file_api.open(test_file);
        assert(fd != -1);
        std::cout << "文件句柄: " << fd << std::endl;
        
        // 写入一些数据
        const char* test_data = "Test close functionality";
        int result = file_api.write(fd, (void*)test_data, strlen(test_data));
        assert(result == static_cast<int>(strlen(test_data)));
        
        // 关闭文件
        int close_result = file_api.close(fd);
        assert(close_result == 1); // 成功返回1
        std::cout << "文件关闭成功" << std::endl;
        
        // 尝试使用已关闭的文件句柄应该失败
        char buffer[100];
        int read_result = file_api.read(fd, buffer, sizeof(buffer));
        assert(read_result == -1); // 读取失败，因为文件已关闭
        
        std::cout << "close 功能测试通过!" << std::endl << std::endl;
    }

    // 运行所有测试
    void run_all_tests() {
        std::cout << "开始文件API测试..." << std::endl << std::endl;
        
        test_single_thread_write();
        test_single_thread_read();
        test_multiple_write_read();
        test_large_file_write();
        test_concurrent_write();
        test_error_handling();
        test_file_handle_management();
        test_close_functionality(); // 新增的测试
        
        std::cout << "所有测试完成!" << std::endl;
    }
};

int main() {
    try {
        std::cout << "文件API测试程序启动..." << std::endl;
        
        // 创建测试实例
        FileApiTest test;
        
        // 运行功能测试
        test.run_all_tests();
        
        std::cout << "所有测试完成，程序退出。" << std::endl;
        
    } catch(const std::exception& e) {
        std::cerr << "测试过程中发生异常: " << e.what() << std::endl;
        return 1;
    }
    
    return 0;
}